﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace ObjectBakery.Helpers
{
    public class StringHelper
    {
        //TODO This is C# specific.  Make work for all supported languages.
        public string PrepareSourceSpool(List<string> lstSource, Language language)
        {
            StringBuilder sbPreparedBodies = new StringBuilder();
            StringBuilder sbPreparedUsings = new StringBuilder();

            Dictionary<string, string> srcDict = new Dictionary<string, string>();

            //set regex to source code language
            Regex rxImport;
            switch (language)
            {
                case Language.CSharp:
                    rxImport = new Regex(@"^using\s+[\w\.]+;$", RegexOptions.Compiled);
                    break;
                default:
                    throw new NotImplementedException("Need Regexs for Import text patterns in other supported languages");
            }


            lstSource.ForEach(src =>
            {
                //bodies are key and usings are val
                var kvp = SplitSpool(rxImport, src);
                sbPreparedUsings.AppendLine(kvp.Value);
                sbPreparedBodies.AppendLine(kvp.Key);
            });


            string uniqueUsings = UniqueSpool(sbPreparedUsings.ToString());
            string unionedBodies = sbPreparedBodies.ToString();
            string unionedWhole = uniqueUsings + unionedBodies;

            return unionedWhole;
        }

        /// <summary>
        /// Seperates lines that match a Regex.  They are returned on the Value, while the Key holds the remaining content.
        /// Example: new Regex(@"^using\s+[\w\.]+;$"); //C# using statement.
        /// </summary>
        /// <param name="rxUsing"></param>
        /// <param name="spool"></param>
        /// <returns></returns>
        public KeyValuePair<string, string> SplitSpool(Regex rxUsing, string spool)
        {
            StringBuilder sbUsings = new StringBuilder();
            StringBuilder sbRest = new StringBuilder();
            StringReader reader = new StringReader(spool);
            {
                while (reader.Peek() != -1)
                {
                    string line = reader.ReadLine().Trim();
                    if (rxUsing.IsMatch(line))
                        sbUsings.AppendLine(line);
                    else
                        sbRest.AppendLine(line);
                }
            }

            return new KeyValuePair<string, string>(sbRest.ToString(), sbUsings.ToString());
        }

        /// <summary>
        /// Removes redundant lines from text
        /// </summary>
        /// <param name="spool"></param>
        /// <returns></returns>
        public string UniqueSpool(string spool)
        {
            List<string> uniqueList = new List<string>();
            //load
            StringReader reader = new StringReader(spool);
            {
                while (reader.Peek() != -1)
                {
                    string line = reader.ReadLine().Trim();
                    if (!uniqueList.Contains(line))
                        uniqueList.Add(line);
                }
            }

            StringBuilder sbUniqueSpool = new StringBuilder();
            uniqueList.ForEach(line =>
            {
                sbUniqueSpool.AppendLine(line);
            });

            return sbUniqueSpool.ToString();
        }
    }
}
